1   /*
2    * Copyright (C) 2007 The Guava Authors
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package com.google.common.collect;
18  
19  import static com.google.common.base.Preconditions.checkNotNull;
20  
21  import com.google.common.annotations.GwtCompatible;
22  
23  import java.util.Collection;
24  import java.util.Comparator;
25  import java.util.SortedSet;
26  import java.util.TreeMap;
27  import java.util.TreeSet;
28  
29  import javax.annotation.Nullable;
30  
31  /**
32   * Implementation of {@code Multimap} whose keys and values are ordered by
33   * their natural ordering or by supplied comparators. In all cases, this
34   * implementation uses {@link Comparable#compareTo} or {@link
35   * Comparator#compare} instead of {@link Object#equals} to determine
36   * equivalence of instances.
37   *
38   * <p><b>Warning:</b> The comparators or comparables used must be <i>consistent
39   * with equals</i> as explained by the {@link Comparable} class specification.
40   * Otherwise, the resulting multiset will violate the general contract of {@link
41   * SetMultimap}, which it is specified in terms of {@link Object#equals}.
42   *
43   * <p>The collections returned by {@code keySet} and {@code asMap} iterate
44   * through the keys according to the key comparator ordering or the natural
45   * ordering of the keys. Similarly, {@code get}, {@code removeAll}, and {@code
46   * replaceValues} return collections that iterate through the values according
47   * to the value comparator ordering or the natural ordering of the values. The
48   * collections generated by {@code entries}, {@code keys}, and {@code values}
49   * iterate across the keys according to the above key ordering, and for each
50   * key they iterate across the values according to the value ordering.
51   *
52   * <p>The multimap does not store duplicate key-value pairs. Adding a new
53   * key-value pair equal to an existing key-value pair has no effect.
54   *
55   * <p>Null keys and values are permitted (provided, of course, that the
56   * respective comparators support them). All optional multimap methods are
57   * supported, and all returned views are modifiable.
58   *
59   * <p>This class is not threadsafe when any concurrent operations update the
60   * multimap. Concurrent read operations will work correctly. To allow concurrent
61   * update operations, wrap your multimap with a call to {@link
62   * Multimaps#synchronizedSortedSetMultimap}.
63   *
64   * <p>See the Guava User Guide article on <a href=
65   * "http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multimap">
66   * {@code Multimap}</a>.
67   *
68   * @author Jared Levy
69   * @author Louis Wasserman
70   * @since 2.0 (imported from Google Collections Library)
71   */
72  @GwtCompatible(serializable = true, emulated = true)
73  public class TreeMultimap<K, V> extends AbstractSortedKeySortedSetMultimap<K, V> {
74    private transient Comparator<? super K> keyComparator;
75    private transient Comparator<? super V> valueComparator;
76  
77    /**
78     * Creates an empty {@code TreeMultimap} ordered by the natural ordering of
79     * its keys and values.
80     */
81    public static <K extends Comparable, V extends Comparable>
82        TreeMultimap<K, V> create() {
83      return new TreeMultimap<K, V>(Ordering.natural(), Ordering.natural());
84    }
85  
86    /**
87     * Creates an empty {@code TreeMultimap} instance using explicit comparators.
88     * Neither comparator may be null; use {@link Ordering#natural()} to specify
89     * natural order.
90     *
91     * @param keyComparator the comparator that determines the key ordering
92     * @param valueComparator the comparator that determines the value ordering
93     */
94    public static <K, V> TreeMultimap<K, V> create(
95        Comparator<? super K> keyComparator,
96        Comparator<? super V> valueComparator) {
97      return new TreeMultimap<K, V>(checkNotNull(keyComparator),
98          checkNotNull(valueComparator));
99    }
100 
101   /**
102    * Constructs a {@code TreeMultimap}, ordered by the natural ordering of its
103    * keys and values, with the same mappings as the specified multimap.
104    *
105    * @param multimap the multimap whose contents are copied to this multimap
106    */
107   public static <K extends Comparable, V extends Comparable>
108       TreeMultimap<K, V> create(Multimap<? extends K, ? extends V> multimap) {
109     return new TreeMultimap<K, V>(Ordering.natural(), Ordering.natural(),
110         multimap);
111   }
112 
113   TreeMultimap(Comparator<? super K> keyComparator,
114       Comparator<? super V> valueComparator) {
115     super(new TreeMap<K, Collection<V>>(keyComparator));
116     this.keyComparator = keyComparator;
117     this.valueComparator = valueComparator;
118   }
119 
120   private TreeMultimap(Comparator<? super K> keyComparator,
121       Comparator<? super V> valueComparator,
122       Multimap<? extends K, ? extends V> multimap) {
123     this(keyComparator, valueComparator);
124     putAll(multimap);
125   }
126 
127   /**
128    * {@inheritDoc}
129    *
130    * <p>Creates an empty {@code TreeSet} for a collection of values for one key.
131    *
132    * @return a new {@code TreeSet} containing a collection of values for one
133    *     key
134    */
135   @Override SortedSet<V> createCollection() {
136     return new TreeSet<V>(valueComparator);
137   }
138 
139   @Override
140   Collection<V> createCollection(@Nullable K key) {
141     if (key == null) {
142       keyComparator().compare(key, key);
143     }
144     return super.createCollection(key);
145   }
146 
147   /**
148    * Returns the comparator that orders the multimap keys.
149    */
150   public Comparator<? super K> keyComparator() {
151     return keyComparator;
152   }
153 
154   @Override
155   public Comparator<? super V> valueComparator() {
156     return valueComparator;
157   }
158 
159   /*
160    * The following @GwtIncompatible methods override the methods in 
161    * AbstractSortedKeySortedSetMultimap, so GWT will fall back to the ASKSSM implementations,
162    * which return SortedSets and SortedMaps.
163    */
164 }
165